#ifndef __QTCH_TIMER_H__
#define __QTCH_TIMER_H__

#include <memory>
#include <list>
#include <functional>
#include <vector>
#include <set>

#include "mutex.h"

namespace qtch{
class TimerManager;

class Timer : public std::enable_shared_from_this<Timer>{
friend class TimerManager;
public:
    typedef std::shared_ptr<Timer> ptr;
    bool cancel();
    bool reflush();
    bool reset(uint64_t ms,bool from_now);
    ~Timer(){
        m_manger = nullptr;
    }
private:
    struct Comparator{
        bool operator()(const Timer::ptr & lhs,const Timer::ptr& rhs) const;
    };
    Timer(uint64_t ms, std::function<void()> cb, bool recurring, TimerManager* manager);
    Timer(uint64_t ms);
    
    bool m_recurring = false;
    uint64_t m_ms = 0;
    uint64_t next_time;
    std::function<void()> m_cb = nullptr;
    TimerManager* m_manger = nullptr;
};

class TimerManager {
    friend class Timer;
public:
    typedef std::shared_ptr<TimerManager> ptr;
    typedef RWMutex RWMutexType;
    TimerManager();
    ~TimerManager();

    Timer::ptr addTimer(uint64_t ms, std::function<void()> cb, bool recurring = false);
    Timer::ptr addConditionTimer(uint64_t ms, std::function<void()> cb,
                     std::weak_ptr<void> weak_cond, bool recurring = false);
    uint64_t getNextTime();
    void listExpectTimer(std::vector<std::function<void()> >& cbs);
    bool hasNextTimer();
    virtual void onTimerInsertedAtFront() = 0;

    void delAllTimer();

private:
    RWMutexType m_mutex;
    std::set<Timer::ptr, Timer::Comparator> m_timers;
    bool m_tickle = false;
};


}




#endif